@file:Suppress("unused")

package com.hjh.tool.util

import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.core.content.FileProvider
import androidx.core.net.toUri
import com.elvishew.xlog.XLog
import com.hjq.toast.Toaster
import java.io.File
import java.io.FileOutputStream
import kotlin.also
import kotlin.apply
import kotlin.collections.mapNotNull
import kotlin.io.copyTo
import kotlin.io.use


/**
 * @author： hjh
 * @createDate： 2025/3/25 10:48
 * @description：
 * @qq： 3472903821
 * @version: 1.0
 */
object ApkInstallUtil {

    // 在 Activity 或 Context 中
    fun getAppName(context: Context): String? {
        try {
            val packageManager: PackageManager = context.packageManager
            val appInfo = packageManager.getApplicationInfo(context.packageName, 0)
            return packageManager.getApplicationLabel(appInfo) as String
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
            return null
        }
    }

    /**
     * 将 assets 中的 APK 复制到应用私有目录
     */
    @Suppress("unused")
    fun copyApkFromAssets(context: Context, apkName: String): File? {
        return try {
            val assetManager = context.assets
            val inputStream = assetManager.open(apkName)
            val outputDir = context.getExternalFilesDir(null) ?: context.filesDir
            val outputFile = File(outputDir, apkName)

            FileOutputStream(outputFile).use { output ->
                inputStream.copyTo(output)
                output.flush()
            }
            outputFile
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    /**
     * 启动安装流程
     */
    @SuppressLint("ObsoleteSdkInt")
    fun installApk(context: Context, apkFile: File) {
        // 验证APK文件有效性
        if (!apkFile.exists() || !apkFile.canRead()) {
            Toaster.showLong("APK文件不可用: $apkFile \n${apkFile.exists()}, ${apkFile.canRead()}")
            return
        }

        // 检查安装权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !context.packageManager.canRequestPackageInstalls()) {
            val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply {
                data = "package:${context.packageName}".toUri()
            }
            context.startActivity(intent)
            Toaster.showLong("请先开启安装未知来源权限")
            return
        }

        val apkUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // 确保FileProvider已正确配置
            try {
                FileProvider.getUriForFile(
                    context, "${context.packageName}.fileprovider", // 必须与manifest中配置一致
                    apkFile
                ).also { uri ->
                    // 显式授予临时权限
                    context.grantUriPermission(
                        context.packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION
                    )
                }
            } catch (e: Exception) {
                Toaster.showLong("获取文件URI失败")
                XLog.e("获取文件URI失败: ${e.message}")
                return
            }
        } else {
            Uri.fromFile(apkFile)
        }

        val installIntent = Intent(Intent.ACTION_VIEW).apply {
            setDataAndType(apkUri, "application/vnd.android.package-archive")
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

            // 对Android 7.0+额外授权
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
        }

        // 直接使用startActivity而不是PendingIntent
        try {
            context.startActivity(installIntent)
        } catch (e: ActivityNotFoundException) {
            Toaster.showLong("未找到可以处理APK安装的应用")
        } catch (e: SecurityException) {
            Toaster.showLong("安装权限被拒绝")
        }
    }

    /**
     * 检查应用是否安装
     */
    fun isInstalled(context: Context, packageName: String): Boolean {
        return try {
            context.packageManager.getPackageInfo(packageName, 0)
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }
    }

    // 获取应用列表
    @SuppressLint("QueryPermissionsNeeded")
    fun getAppList(context: Context): List<AppInfo> {
        val packageManager = context.packageManager
        return packageManager.getInstalledApplications(PackageManager.GET_META_DATA)
            .mapNotNull { app ->
                try {
                    AppInfo(
                        name = app.loadLabel(packageManager).toString(),
                        packageName = app.packageName,
                        icon = app.loadIcon(packageManager),
                        versionName = packageManager.getPackageInfo(app.packageName, 0).versionName
                            ?: "N/A"
                    )
                } catch (e: Exception) {
                    null // 忽略异常应用
                }
            }
    }

    // 定义数据类
    data class AppInfo(
        val name: String,
        val packageName: String,
        val icon: Drawable?,
        val versionName: String
    )
}